package br.ufc.great.dtxtester.operation;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Random;
import java.util.Vector;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import br.ufc.great.client.DTXInsertOperation;
import br.ufc.great.xml.XMLAttribute;
import br.ufc.great.xml.XMLElement;
import br.ufc.great.xml.XMLNode;

/**
 * 
 * @author Leonardo Oliveira Moreira
 *
 * Classe utilizada para recuperar opera��es de inser��o atrav�s de um arquivo XML com exemplos de inser��es
 */
public class InsertOperations {

	private Document document;
	private Random random;
	private Vector<InsertOperation> insertOperations;
	
	/**
	 * Construtor
	 * 
	 * @param fileName
	 * @throws IOException
	 */
	public InsertOperations(String fileName) throws IOException {
		SAXBuilder saxBuilder = new SAXBuilder();
		String appPath = System.getProperty("user.dir");
		if (appPath.endsWith("bin"))
			appPath = appPath.substring(0, appPath.length() - "bin".length());
		appPath += System.getProperty("file.separator");
		File file = new File(appPath + fileName);
	    try {
			document = saxBuilder.build(file);
			random = new Random();
		    Element insertOperationsRoot = document.getRootElement();
		    List insertOperationsList = insertOperationsRoot.getChildren();
		    insertOperations = new Vector<InsertOperation>();
	    	for (int i = 0; i < insertOperationsList.size(); i++) {
			    Element item = (Element) insertOperationsList.get(i);
		    	String id = item.getAttributeValue("id");
		    	Element insertType = item.getChild("into");
		    	if (insertType != null) {
			    	int type = DTXInsertOperation.INTO;
			    	String query = insertType.getValue().trim();
			    	XMLElement constructor = null;
			    	Element node = item.getChild("node");
			    	if (node != null) {
			    		XMLNode newNode = new XMLNode(0, null);
	    				newNode.setName(node.getAttributeValue("name"));
			    		Vector<XMLAttribute> newAttributes = new Vector<XMLAttribute>();
			    		List nodeChildrens = node.getChildren();
			    		for (int j = 0; j < nodeChildrens.size(); j++) {
			    			Element element = (Element) nodeChildrens.get(j);
			    			if (element.getName().equalsIgnoreCase("attribute")) {
			    				XMLAttribute attr = new XMLAttribute(0, element.getAttributeValue("name"), element.getValue(), newNode);
			    				newAttributes.add(attr);
			    			}
			    			else {
			    				newNode.setValue(element.getValue());
			    			}
			    		}
			    		newNode.setAttributes(newAttributes);
			    		constructor = newNode;
			    	}
			    	Element attribute = item.getChild("attribute");
			    	if (attribute != null) {
			    		XMLAttribute newAttribute = new XMLAttribute(0, attribute.getAttributeValue("name"), attribute.getValue(), null);
			    		constructor = newAttribute;
			    	}
			    	InsertOperation operation = new InsertOperation();
			    	operation.setId(id);
			    	operation.setType(type);
			    	operation.setQuery(query);
			    	operation.setConstructor(constructor);
			    	insertOperations.add(operation);
		    	}
	    	}		    
		}
	    catch (JDOMException e) {
			throw new IOException(e.getMessage());
		}
	    catch (IOException e) {
			throw e;
		}
	}
	
	/**
	 * Método que retorna aleatoriamente uma opera��o de inser��o contida no arquivo
	 * 
	 * @return
	 */
	public InsertOperation getOperation() {
	    if (insertOperations != null && insertOperations.size() > 0) {
	    	return insertOperations.elementAt(random.nextInt(insertOperations.size() - 1));
	    }
	    return null;
	}
	
	public InsertOperation getOperation(String id) {
		for (int i = 0; insertOperations != null && i < insertOperations.size(); i++) {
			InsertOperation insrrtOperation = insertOperations.elementAt(i);
			if (insrrtOperation.getId().equalsIgnoreCase(id))
				return insrrtOperation;
		}
		return null;
	}

}
